//*************************************************************************************
/** \file task_battery.h
 *    This file contains a class which battery charge controller. The charge controller
 *    is used to maintain the energy level in a lead-acid battery using a solar panel
 *    with a shunt transistor to deactivate solar charging when the battery is full.
 *    The battery voltage is monitored and can be transmitted with a radio modem to
 *    allow the system's condition to be monitored remotely. 
 *
 *  Revisions:
 *    \li 12-26-2007 JRR Original file
 *    \li 12-30-2007 JRR Corrected spelling of Fahrenheit
 *    \li 06-01-2008 JRR Changed serial stuff to use base_text_serial and descendents
 *    \li 09-19-2009 JRR Battery charge control task adapted from temperature task
 */
//*************************************************************************************

/// This define prevents this file from being included more than once in a *.cc file
#ifndef _TASK_BATTERY_H_
#define _TASK_BATTERY_H_

#include "stl_task.h"						// Include header for base task class
#include "adc_10bit.h"						// Header for A/D converter driver class


/// This is the number of times to read the A/D battery channel to reduce noise. 
#define BATT_OVERSAMPLE		20

/// This is the threshold voltage reading at which charging is stopped. 
#define BATT_MAX_A2D		1340

/// This is the threshold voltage reading below which charging must resume. 
#define BATT_MIN_A2D		1250

// Settings for the calibration numerator and denominator:  
//    For 120K/12K voltage divider and 5V AVCC reference:  215/40
//    For 100K/10K divider, seems off, change to 245/40 and it's about right(?!)
//    For 100K/10K divider and internal 2.56V reference, try 215/20

/** This is the numerator by which A/D readings are multiplied to get voltage; it
 *  should be less than 256 so the voltage doesn't overflow 16 bit integers. */
#define BATT_NUMER			215

/// This is the denominator by which A/D readings are divided to get voltage. 
#define BATT_DENOM			20

/// This is the number of battery full measurements before we turn on the shunt and 
/// stop charging until the battery is found to be not full anymore
#define BATT_FULL_MAX_CT	10

/// This is the number of battery empty measurements before we turn off the shunt and 
/// restart charging until the battery is found to be filled up again
#define BATT_EMPTY_MAX_CT	10


//-------------------------------------------------------------------------------------
/** This class contains a task which controls a solar panel charging a lead-acid
 *  battery. The charge control monitors the battery voltage and deactivates the panel
 *  (by design with a shunt transistor) when the battery voltage gets above the safe
 *  charge threshold. 
 */

class task_battery : public stl_task
{
	protected:
		/// This is a pointer to the A/D converter object used to read the voltage
		adc_10bit* p_the_adc;

		/// This is the A/D converter channel used to read battery voltage
		uint8_t adc_chan;

		/// This is the name of the I/O port where the shunt control pin is
		volatile uint8_t& ctrl_port;

		/// This is the name of the data direction register for the control port
		volatile uint8_t& ctrl_ddr;

		/// This bitmask controls which pin is used to activate the panel shunt
		uint8_t ctrl_mask;

		/// This is the most recently taken voltage reading
		uint16_t most_recent_voltage;

		/// This variable counts the number of full-battery readings
		uint8_t full_counter;

		/// This variable counts the number of full-battery readings
		uint8_t empty_counter;

	public:
		// The constructor creates a new battery charge controller task object
		task_battery (adc_10bit*, uint8_t, volatile uint8_t&, volatile uint8_t&, 
					   uint8_t, task_timer&, time_stamp);

		// The run method is where the task actually performs its function
		char run (char);

		// This method returns the most recently computed voltage
		uint16_t get_voltage (void);
};


// This operator allows a battery voltage to be easily sent to a serial device
base_text_serial& operator<< (base_text_serial&, task_battery&);


#endif // _TASK_BATTERY_H_
